<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title> show love</title>
    <script>
      window.onload = function() {
        var canvas = document.getElementById('canvas');
        var ctx = canvas.getContext('2d');
        var garden = new Garden(canvas);

        // x=r*sinθ*cosΦ   y=r*sinθ*sinΦ   z=r*cosθ;
        // θ = arccos((2*num-1)/all - 1);
        // Φ = θ*sqrt(all * π);

        // for(var i = 0; i <= 180; i += 10)
        //   for(var j = 0; j <= 360; j += 10) {
        //     var a1 = Math.PI / 180 * i;
        //     var a2 = Math.PI / 180 * j;
        //     var x = 150 * Math.sin(a1) * Math.cos(a2);
        //     var y = 150 * Math.sin(a1) * Math.sin(a2);
        //     var z = 150 * Math.cos(a1);
        //     garden.createBall(x, y, z);
        //   }
        for(var i = 10; i <= 30; i += 0.2) {
          var ans = getHeartPoint(i);
          garden.createBall(ans[0], ans[1], -50);
          garden.createBall(ans[0], ans[1], 0);

          // ctx.beginPath();
          // ctx.arc(ans[0], ans[1], 1, 0, Math.PI * 2, true);
          // ctx.fill();
        }

        function getHeartPoint(angle) {
           var t = angle / Math.PI;
           var sx = 10;
           var sy = -10;
           var x = sx * (16 * Math.pow(Math.sin(t), 3));
           var y = sy * (13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t));
           return new Array(x, y);
        }

        // var all = 50;
        // for(var i = 1; i <= all; i++) {
        //   garden.createBall();
        // }

        document.addEventListener("mousemove" , function(event){
          var x = event.clientX - garden.vpx;
          var y = event.clientY - garden.vpy;

          garden.angleY = -x * 0.0001;
          garden.angleX = y * 0.0001;
        });

        setInterval(function() {garden.render();}, 1000/60);
        // for(var i = 0; i < garden.balls.length; i++)
          // console.log("%d %d %d", garden.balls[i].x, garden.balls[i].y, garden.balls[i].z)
      };

      function Garden(canvas, vpx, vpy) {
        this.canvas = canvas;
        this.ctx = this.canvas.getContext('2d');

        // 三维系在二维上的原点
        this.vpx = vpx === undefined? 500: vpx;
        this.vpy = vpy === undefined? 250: vpy;
        this.balls = [];
        this.angleY = Math.PI / 180;
        this.angleX = 0;
      }

      Garden.prototype = {
        createBall: function(x, y, z) {
          this.balls.push(new Ball(this, x, y, z));
        },

        render: function() {
          this.ctx.clearRect(0,0,1600,700)
          // this.balls.sort(function (a, b) {return b.z-a.z })
          for(var i = 0; i < this.balls.length; i++) {
            this.balls[i].rotateY();
            this.balls[i].rotateX();
            this.balls[i].draw(i);
          }
        }
      };

      function Ball(garden, x, y, z, angleX, angleY, ballR) {
        this.garden = garden;

        // 三维下坐标
        this.x = x === undefined? Math.random() * 800 : x;
        this.y = y === undefined? Math.random() * 200 : y;
        this.z = z === undefined? Math.random() * 400 - 200: z;

        this.r = Math.floor(Math.random() * 255);
        this.g = Math.floor(Math.random() * 255);
        this.b = Math.floor(Math.random() * 255);

        this.fontSize = (10 + 10 * Math.random());

        // this.angleX = 0;
        // this.angleX = angleX || Math.PI / 200;

        // this.angleY = angleY === undefined? Math.PI / 100: angleY;

        // 三维上半径
        this.ballR = 1;

        // 二维上半径
        this.radius = undefined;

        // 二维上坐标
        this.x2 = undefined;
        this.y2 = undefined;
      }


      Ball.prototype = {
        // 绕y轴变化，得出新的x，z坐标
        rotateY: function() {
          var cosy = Math.cos(this.garden.angleY);
          var siny = Math.sin(this.garden.angleY);
          var x1 = this.z * siny + this.x * cosy;
          var z1 = this.z * cosy - this.x * siny;

          this.x = x1;
          this.z = z1;

        },

        // 绕x轴变化，得出新的y，z坐标
        rotateX: function() {
          var cosx = Math.cos(this.garden.angleX);
          var sinx = Math.sin(this.garden.angleX);
          var y1 = this.y * cosx - this.z * sinx;
          var z1 = this.y * sinx + this.z * cosx;

          this.y = y1;
          this.z = z1;
        },

        draw: function(a) {
          // focalLength 表示当前焦距，一般可设为一个常量
          var focalLength = 300;

          // 把z方向扁平化
          var scale = focalLength / (focalLength + this.z);
          this.x2 = this.garden.vpx + this.x * scale;
          this.y2 = this.garden.vpy + this.y * scale;
          this.radius = this.ballR * scale;

          this.garden.ctx.beginPath();
          this.garden.ctx.fillStyle = 'rgba('+this.r+','+this.g+','+this.b+','+ Math.min(1, scale)+')';
          this.garden.ctx.arc(this.x2, this.y2, this.radius, 0, Math.PI * 2 , true);
          // this.garden.ctx.font = 'bold ' + this.fontSize * scale+ 'px serif';
          // this.garden.ctx.textAlign = "left";
          // this.garden.ctx.textBaseline = "top";
          // this.garden.ctx.fillText('博客园', this.x2, this.y2);
          this.garden.ctx.fill();

          if(a % 4 === 3) {
            var x1 = this.garden.balls[a - 3].x2;
            var y1 = this.garden.balls[a - 3].y2;
            var x2 = this.garden.balls[a - 2].x2;
            var y2 = this.garden.balls[a - 2].y2;
            var x3 = this.garden.balls[a - 1].x2;
            var y3 = this.garden.balls[a - 1].y2;
            var x4 = this.x2;
            var y4 = this.y2;
            this.garden.ctx.beginPath();
            // this.garden.ctx.strokeStyle = 'rgba('+this.r+','+this.g+','+this.b+','+ Math.min(1, scale)+')';
            this.garden.ctx.moveTo(x1, y1);
            this.garden.ctx.lineTo(x2, y2);
            this.garden.ctx.lineTo(x4, y4);
            this.garden.ctx.lineTo(x3, y3);
            this.garden.ctx.closePath();

            this.garden.ctx.fill();
            // debugger;
          }
        }
      }
    </script>
  </head>
  <body bgcolor='#000'>
    <canvas id='canvas' width=1600 height=500 style='background-color:rgb(0,0,0)'>
      This browser does not support html5.
    </canvas>
  </body>
</html>